package altserial;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;

import java.io.IOException;
import java.io.OutputStream;
import java.util.TreeSet;

public class CodeDownloader {
	private String appName;
	private TreeSet<String> possiblePorts;
	private UploadHandler uploader;
	
	public CodeDownloader(String appName) {
		this.appName = appName;
		possiblePorts = new TreeSet<String>();
	}
	
	public void addPossiblePort(String portName) {
		possiblePorts.add(portName);
	}
	
	public void sendCode(String code) throws IOException {
		SerialPort port = findPossiblePort();
		OutputStream out = port.getOutputStream();
		int numLines = 1;
		for (int i = 0; i < code.length(); ++i) {
    		out.write(code.codePointAt(i));
    		if (code.codePointAt(i) == '\n' && i > 0 && code.codePointAt(i - 1) != '\n') {
    			numLines += 1;
    		}
    	}
		out.close();
		System.out.println("code sent...");
		
		uploader = new UploadHandler(port, numLines);
		uploader.start();
	}
	
	private SerialPort findPossiblePort() {
		for (String port: possiblePorts) {
			SerialPort result = openPort(port);
			if (result != null) {
				return result;
			}
		}
		
		throw new IllegalStateException("No port available");
	}
	
	private SerialPort openPort(String portName) {
		try {
			CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
			SerialPort serialPort = (SerialPort)portIdentifier.open(appName,2000);
			serialPort.setSerialPortParams(57600, SerialPort.DATABITS_8,
					SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
			return serialPort;
		} catch(NoSuchPortException e) {
			return null;
		} catch(PortInUseException e) {
			return null;
		} catch(UnsupportedCommOperationException e) {
			return null;
		}
	}
}
